package com.cq.hd.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cq.hd.common.utils.BeanUtils;
import com.cq.hd.common.utils.StringUtils;
import com.cq.hd.system.api.vo.RegionVo;
import com.cq.hd.system.po.TbRegionsPo;
import com.cq.hd.system.mapper.TbRegionsMapper;
import com.cq.hd.system.service.TbRegionsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 地区(es_regions) 服务实现类
 * </p>
 *
 * @author mYunYu
 * @since 2023-11-22
 */
@Service
public class TbRegionsServiceImpl extends ServiceImpl<TbRegionsMapper, TbRegionsPo> implements TbRegionsService {

    public static Map<Integer, RegionVo> provinceInfoMap = new HashMap<>();
    public static Map<Integer, RegionVo> cityInfoMap = new HashMap<>();
    public static List<RegionVo> provinceInfoList = new ArrayList<>();
    public static List<RegionVo> cityInfoList = new ArrayList<>();
    public static List<RegionVo> countyInfoList = new ArrayList<>();

    @PostConstruct
    public void init() {
        provinceInfoList = baseMapper.listRegionByGrade(1);
        cityInfoList = baseMapper.listRegionByGrade(2);

        for (RegionVo regionVo : provinceInfoList) {
            Integer provinceId = regionVo.getId();
            List<RegionVo> provinceRegions = regionVo.getRegions();

            for (RegionVo city : cityInfoList) {
                Integer cityId = city.getId();
                List<RegionVo> cityRegions = city.getRegions();

                if (city.getParentId().equals(provinceId)) {
                    provinceRegions.add(city);
                }

                for (RegionVo county : countyInfoList) {
                    if (county.getParentId().equals(cityId)) {
                        cityRegions.add(county);
                    }

                }
            }
        }

        provinceInfoMap = provinceInfoList.stream().collect(Collectors.toMap(RegionVo::getId, a -> a, (k1, k2) -> k1));
        cityInfoMap = cityInfoList.stream().collect(Collectors.toMap(RegionVo::getId, a -> a, (k1, k2) -> k1));
    }

    @Override
    public List<RegionVo> listRegion(Integer id) {
        return baseMapper.listRegionByParentId(id);
    }

    @Override
    public List<RegionVo> listAllRegion(String cityName) {
        if (StringUtils.isBlank(cityName)) {
            return provinceInfoList;
        }

        List<RegionVo> regionVos = new ArrayList<>();
        List<TbRegionsPo> tbRegionsPos = baseMapper.selectList(new QueryWrapper<TbRegionsPo>().eq("region_grade", 2).like("local_name", cityName));
        if (!CollectionUtils.isEmpty(tbRegionsPos)) {
            Map<Integer, List<TbRegionsPo>> tbRegionsPoMap = tbRegionsPos.stream().collect(Collectors.groupingBy(TbRegionsPo::getParentId));
            for (Integer provinceId : tbRegionsPoMap.keySet()) {
                RegionVo newRegionVo = new RegionVo();
                RegionVo regionVo = provinceInfoMap.get(provinceId);
                if (regionVo != null) {
                    BeanUtils.copyProperties(regionVo, newRegionVo);
                    newRegionVo.setRegions(null);
                }

                List<TbRegionsPo> cityRegionPos = tbRegionsPoMap.get(provinceId);
                if (!CollectionUtils.isEmpty(cityRegionPos)) {
                    List<RegionVo> cityRegionVos = new ArrayList<>();
                    for (TbRegionsPo cityRegionPo : cityRegionPos) {
                        Integer id = cityRegionPo.getId();
                        RegionVo cityRegionVo = cityInfoMap.get(id);
                        if (cityRegionVo != null) {
                            cityRegionVo.setRegions(null);
                            cityRegionVos.add(cityRegionVo);
                        }
                    }

                    newRegionVo.setRegions(cityRegionVos);
                }

                regionVos.add(newRegionVo);
            }
        }

        return regionVos;
    }
}
